package com.devMode.ObserverMode;

import java.util.ArrayList;
import java.util.List;

/**
 * 观察者模式
 * 对象之间存在一对多依赖关系，当一个对象改变的时候，它所有依赖的对象都会收到通知
 * 并且自动做出相应的动作
 *
 * 主体维护一张观察者的表，它可以移除，或注册观察者，并通知所有观察者
 * 观察者，需要调用主体的注册方法
 */
public class ObserverMode {
    public static void main(String[] args) {
        WeatherSubject weatherSubject = new WeatherSubject();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherSubject);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherSubject);

        weatherSubject.setMeasurements(0,0,0);

        for(int i = 1; i<100; i++){
            weatherSubject.setMeasurements(i,i,i);
        }
    }
}

interface subject{
    void registerObServer(ObServer obServer);

    void removerObServer(ObServer obServer);

    void notifyAllObServer();
}

/**
 * 观察者
 */
interface ObServer{
    void update(double temp, double humidity, double presure);
}

class StatisticsDisplay implements ObServer{
    public StatisticsDisplay(subject weatherData){
        weatherData.registerObServer(this);
    }

    @Override
    public void update(double temp, double humidity, double presure) {
        System.out.println("StatisticsDisplay update : "+temp + " " + humidity + " " + presure);
    }
}

class CurrentConditionsDisplay implements ObServer{
    public CurrentConditionsDisplay(subject weatherData){
        weatherData.registerObServer(this);
    }

    @Override
    public void update(double temp, double humidity, double presure) {
        System.out.println("CurrentConditionsDisplay  update : "+temp + " " + humidity + " " + presure);
    }
}

/**
 * 天气预报，每次天气发生变更都会通知其观察者们
 */
class WeatherSubject implements subject{
    private List<ObServer> observers;
    private double temperature;
    private double humidity;
    private double presure;

    public WeatherSubject(){
        observers = new ArrayList<>();
    }

    public void setMeasurements(double temperature , double humidity, double presure){
        this.temperature = temperature;
        this.humidity = humidity;
        this.presure = presure;
        notifyAllObServer();
    }

    @Override
    public void registerObServer(ObServer obServer) {
        observers.add(obServer);

    }

    @Override
    public void removerObServer(ObServer obServer) {
        int i = observers.indexOf(obServer);
        if(i>=0)
            observers.remove(i);
    }

    @Override
    public void notifyAllObServer() {
        for(ObServer obServer : observers)
            obServer.update(this.temperature,this.humidity,this.presure);
    }

}


